package com.gqh.weather.service;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gqh.weather.auth.UserContext;
import com.gqh.weather.domain.dto.*;
import com.gqh.weather.domain.entity.Paper;
import com.gqh.weather.domain.entity.Question;
import com.gqh.weather.domain.enums.TiXingEnum;
import com.gqh.weather.domain.enums.XuekeEnum;
import com.gqh.weather.exception.BusinessException;
import com.gqh.weather.exception.Result;
import com.gqh.weather.mapper.PaperMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 试卷管理服务类
 *
 * @author AI
 * @date 2025-10-20
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class PaperService extends ServiceImpl<PaperMapper, Paper> {

    private final PaperMapper paperMapper;
    private final QuestionService questionService;

    /**
     * 创建试卷
     *
     * @param request 创建请求
     * @return 操作结果
     */
    public Result<Void> createPaper(PaperCreateRequest request) {
        try {
            // 获取当前用户ID
            Integer currentUserId = UserContext.getCurrentUserId();

            // 验证学科类型
            if (XuekeEnum.fromValue(request.getType()) == null) {
                throw new BusinessException("学科类型错误");
            }

            // 构建Paper实体
            Paper paper = new Paper();
            paper.setName(request.getName());
            paper.setDesc(request.getDesc());
            paper.setType(request.getType());
            paper.setScore(request.getScore());
            paper.setData(request.getData());
            Integer passScore = request.getPass_score();
            if (passScore == null) {
                // 如果及格分数为空，设置为总分的60%
                passScore = (int) (request.getScore() * 0.6);
            }
            paper.setPassScore(passScore);
            paper.setCreatedBy(currentUserId);
            paper.setIfPublish(0); // 默认未发布
            paper.setIsDeleted(0); // 默认未删除

            // 保存到数据库
            boolean saved = this.save(paper);
            if (!saved) {
                throw new BusinessException("创建试卷失败");
            }

            log.info("试卷创建成功, ID: {}, 创建人: {}", paper.getId(), currentUserId);
            return Result.success(null);
        } catch (BusinessException e) {
            log.error("创建试卷失败: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("创建试卷发生系统错误", e);
            throw new BusinessException("系统错误");
        }
    }
    /**
     * 随机试卷
     *
     * @param request 创建请求
     * @return 操作结果
     */
    public Result<Void> randomPaper(PaperRandomRequest request) {
        try {
            // 获取当前用户ID
            Integer currentUserId = UserContext.getCurrentUserId();

            // 验证学科类型
            if (XuekeEnum.fromValue(request.getType()) == null) {
                throw new BusinessException("学科类型错误");
            }

            // 构建Paper实体
            Paper paper = new Paper();
            paper.setName(request.getName());
            paper.setDesc(request.getDesc());
            paper.setType(request.getType());
            paper.setData(request.getData());
            paper.setCreatedBy(currentUserId);
            paper.setIfPublish(0); // 默认未发布
            paper.setIsDeleted(0); // 默认未删除

            int score = 0;

            String data = paper.getData();
            List<PaperInfo.PaperInfoData> paperInfoDatas = new ObjectMapper().readValue(data, new TypeReference<List<PaperInfo.PaperInfoData>>() {
            });

            for (PaperInfo.PaperInfoData paperInfoData : paperInfoDatas) {
                Integer size = Integer.valueOf(paperInfoData.getQnum());
                Integer qType = Integer.valueOf(paperInfoData.getQtype());

                score = score + paperInfoData.getScore();

                QuestionRandomRequest randomRequest = new QuestionRandomRequest();
                randomRequest.setDifficulty(request.getDifficulty());
                randomRequest.setType(request.getType());
                randomRequest.setSize(size);
                randomRequest.setQtype(qType);
                randomRequest.setIfPublish(1);
                Result<List<Integer>> ids = questionService.random(randomRequest);
                if (ids.getData().size() < size) {
                    throw new BusinessException("题型" + paperInfoData.getTname() + "题库不足");
                }
                paperInfoData.setQids(ids.getData());
            }
            paper.setScore(score);
            paper.setData(new ObjectMapper().writeValueAsString(paperInfoDatas));
            
            // 如果及格分数为空，设置为总分的60%
            Integer passScore = request.getPass_score();
            if (passScore == null) {
                passScore = (int) (score * 0.6);
            }
            paper.setPassScore(passScore);

            // 保存到数据库
            boolean saved = this.save(paper);
            if (!saved) {
                throw new BusinessException("创建试卷失败");
            }

            log.info("试卷创建成功, ID: {}, 创建人: {}", paper.getId(), currentUserId);
            return Result.success(null);
        } catch (BusinessException e) {
            log.error("创建试卷失败: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("创建试卷发生系统错误", e);
            throw new BusinessException("系统错误");
        }
    }

    /**
     * 更新试卷
     *
     * @param request 更新请求
     * @return 操作结果
     */
    public Result<Void> updatePaper(PaperUpdateRequest request) {
        try {
            // 查询试卷是否存在（自动过滤已删除数据）
            Paper existingPaper = this.getById(request.getId());
            if (existingPaper == null) {
                throw new BusinessException("试卷不存在");
            }

            // 验证学科类型
            if (XuekeEnum.fromValue(request.getType()) == null) {
                throw new BusinessException("学科类型错误");
            }

            // 构建更新实体
            Paper paper = new Paper();
            paper.setId(request.getId());
            paper.setName(request.getName());
            paper.setDesc(request.getDesc());
            paper.setType(request.getType());
            paper.setScore(request.getScore());
            paper.setData(request.getData());
            
            // 如果及格分数为空，设置为总分的60%
            Integer passScore = request.getPass_score();
            if (passScore == null) {
                passScore = (int) (request.getScore() * 0.6);
            }
            paper.setPassScore(passScore);

            // 更新试卷
            boolean updated = this.updateById(paper);
            if (!updated) {
                throw new BusinessException("更新试卷失败");
            }

            log.info("试卷更新成功, ID: {}", request.getId());
            return Result.success(null);
        } catch (BusinessException e) {
            log.error("更新试卷失败: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("更新试卷发生系统错误", e);
            throw new BusinessException("系统错误");
        }
    }

    /**
     * 批量删除试卷（逻辑删除）
     * 使用MyBatis-Plus的逻辑删除功能，自动将is_deleted设置为1
     *
     * @param ids 试卷ID列表
     * @return 操作结果
     */
    public Result<Void> deletePapers(List<Integer> ids) {
        try {
            if (ids == null || ids.isEmpty()) {
                throw new BusinessException("试卷ID列表不能为空");
            }

            // 使用MyBatis-Plus的批量删除方法，会自动执行逻辑删除
            // 实际执行: UPDATE xy_paper SET is_deleted = 1 WHERE id IN (...) AND is_deleted = 0
            boolean removed = this.removeByIds(ids);
            if (!removed) {
                throw new BusinessException("删除试卷失败");
            }

            log.info("批量删除试卷成功, 删除数量: {}", ids.size());
            return Result.success(null);
        } catch (BusinessException e) {
            log.error("删除试卷失败: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("删除试卷发生系统错误", e);
            throw new BusinessException("系统错误");
        }
    }

    /**
     * 分页查询试卷列表
     *
     * @param request 查询请求
     * @return 分页结果
     */
    public Result<MyPage<PaperListData>> listPapers(PaperListRequest request) {
        try {
            // 获取当前用户ID
            Integer currentUserId = UserContext.getCurrentUserId();

            // 验证学科类型（如果指定）
            if (request.getType() != null && request.getType() != 0) {
                if (XuekeEnum.fromValue(request.getType()) == null) {
                    throw new BusinessException("学科类型错误");
                }
            }

            // 构建分页对象
            Page<PaperListData> page = request.toPage();

            // 执行分页查询（使用自定义SQL关联查询创建人信息）
            Page<PaperListData> resultPage = paperMapper.selectPaperListWithCreator(
                    page,
                    currentUserId,
                    request.getType(),
                    request.getIfPublish(),
                    request.getKeyword()
            );

            // 转换为MyPage格式
            MyPage<PaperListData> myPage = MyPage.fromMybatisPlusPage(resultPage);

            log.info("查询试卷列表成功, 用户ID: {}, 总记录数: {}", currentUserId, myPage.getTotal());
            return Result.success(myPage);
        } catch (BusinessException e) {
            log.error("查询试卷列表失败: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("查询试卷列表发生系统错误", e);
            throw new BusinessException("系统错误");
        }
    }

    /**
     * 查询试卷详情（包含解析后的试卷内容）
     * MyBatis-Plus的逻辑删除会自动过滤is_deleted=1的数据
     * 按照Go代码逻辑，填充题目详情和子题目详情
     *
     * @param id 试卷ID
     * @return 试卷详情
     */
    public Result<PaperInfo> getPaperInfo(Integer id) {
        try {
            // MyBatis-Plus会自动添加 WHERE is_deleted = 0 条件
            // 实际执行: SELECT * FROM xy_paper WHERE id = #{id} AND is_deleted = 0
            Paper paper = this.getById(id);
            if (paper == null) {
                throw new BusinessException("试卷不存在");
            }

            // 转换为 PaperInfo
            PaperInfo paperInfo = new PaperInfo();
            org.springframework.beans.BeanUtils.copyProperties(paper, paperInfo);

            // 解析 data 字段（JSON 字符串）为 List<PaperInfoData> 对象
            if (paper.getData() != null && !paper.getData().isEmpty()) {
                try {
                    ObjectMapper objectMapper = new ObjectMapper();
                    List<PaperInfo.PaperInfoData> dataInfoList = objectMapper.readValue(
                        paper.getData(), 
                        objectMapper.getTypeFactory().constructCollectionType(
                            List.class, 
                            PaperInfo.PaperInfoData.class
                        )
                    );
                    
                    // 填充每个题型的题目详情（对应Go代码的逻辑）
                    for (PaperInfo.PaperInfoData paperInfoData : dataInfoList) {
                        // 如果qids为空，跳过
                        if (paperInfoData.getQids() == null || paperInfoData.getQids().isEmpty()) {
                            continue;
                        }
                        
                        // 查询题目列表
                        List<Question> questions = questionService.listByIds(paperInfoData.getQids());
                        
                        // 构建QuestionInfos列表
                        List<PaperInfo.QuestionInfos> qinfosList = new ArrayList<>();
                        for (Question question : questions) {
                            PaperInfo.QuestionInfos qinfo = new PaperInfo.QuestionInfos();
                            // 直接复制Question的所有字段到QuestionInfos
                            org.springframework.beans.BeanUtils.copyProperties(question, qinfo);
                            
                            // 处理子题目（如果存在）
                            if (question.getSubid() != null && !question.getSubid().isEmpty() 
                                && !"[]".equals(question.getSubid())) {
                                try {
                                    // 解析subid字段（JSON数组）
                                    List<SubIdInfo> subidInfos = objectMapper.readValue(
                                        question.getSubid(),
                                        objectMapper.getTypeFactory().constructCollectionType(
                                            List.class,
                                            SubIdInfo.class
                                        )
                                    );
                                    
                                    // 查询子题目详情
                                    List<PaperInfo.QuestionData> subQuestions = new ArrayList<>();
                                    for (SubIdInfo subIdInfo : subidInfos) {
                                        Question subQuestion = questionService.getById(subIdInfo.getId());
                                        if (subQuestion != null) {
                                            PaperInfo.QuestionData subQinfo = new PaperInfo.QuestionData();
                                            org.springframework.beans.BeanUtils.copyProperties(subQuestion, subQinfo);
                                            subQuestions.add(subQinfo);
                                        }
                                    }
                                    qinfo.setSubIDInfos(subQuestions);
                                } catch (Exception e) {
                                    log.warn("解析子题目失败, Question ID: {}, 错误: {}", question.getId(), e.getMessage());
                                    qinfo.setSubIDInfos(new ArrayList<>());
                                }
                            } else {
                                qinfo.setSubIDInfos(new ArrayList<>());
                            }
                            
                            qinfosList.add(qinfo);
                        }
                        
                        paperInfoData.setQinfos(qinfosList);
                    }
                    
                    paperInfo.setDataInfo(dataInfoList);
                } catch (Exception e) {
                    log.warn("解析试卷内容失败, ID: {}, 错误: {}", id, e.getMessage());
                    // 解析失败不影响主流程，dataInfo 保持为 null
                }
            }

            log.info("查询试卷详情成功, ID: {}", id);
            return Result.success(paperInfo);
        } catch (BusinessException e) {
            log.error("查询试卷详情失败: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("查询试卷详情发生系统错误", e);
            throw new BusinessException("系统错误");
        }
    }
    
    /**
     * 子题目ID信息类（用于解析subid字段）
     */
    @lombok.Data
    private static class SubIdInfo {
        private Integer id;
        private Integer qtype;
        private String title;
    }
    
    /**
     * 发布/取消发布试卷
     * MyBatis-Plus的逻辑删除会自动过滤和保护已删除的数据
     *
     * @param ids   试卷ID
     * @param flag 发布标志：0取消发布 1发布
     * @return 操作结果
     */
    public Result<Void> publishPaper(List<Integer> ids, Integer flag) {
        try {

            // 使用 UpdateWrapper 来更新，支持设置 null 值
            LambdaUpdateWrapper<Paper> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.in(Paper::getId, ids)
                        .set(Paper::getIfPublish, flag);

            // 执行更新（只会更新未删除的数据）
            boolean updated = this.update(updateWrapper);
            if (!updated) {
                throw new BusinessException("发布操作失败");
            }

            String operation = flag == 1 ? "发布" : "取消发布";
            log.info("{}试卷成功, ID: {}", operation, ids);
            return Result.success(null);
        } catch (BusinessException e) {
            log.error("发布操作失败: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("发布操作发生系统错误", e);
            throw new BusinessException("系统错误");
        }
    }
}